extends Node

signal on_creat_block_text(unit: Node2D)
signal on_create_damage_text(unit: Node2D, hitbox: HitboxComponent)
signal on_create_heal_text(unit: Node2D, heal: float)
signal on_upgrade_selected
signal on_enemy_died(unit: Enemy)

enum UpgradeTier {
	COMMON,
	RARE,
	EPIC,
	LEGENDARY
}

const COINS_SCENE = preload("uid://b3wgmc7b8s2ax")
const ITEM_CARD_SCENE = preload("uid://bskr282e1my8t")
const SELECTION_CARD_SCENE = preload("uid://dit78363ipag3")
const FLOATING_TEXT_SCENE = preload("uid://b40iqr06ajres")
const SPAWN_EFFECT_SCENE = preload("uid://ctfm6rr8r1cxe")

const FLASH_MATERIAL = preload("uid://dq7ylhu6c7i0a")

const COMMON_STYLE = preload("uid://dv2nnip7m2non")
const EPIC_STYLE = preload("uid://dvo12srupcm48")
const RARE_STYLE = preload("uid://dq6t8hwfewt4l")
const LEGENDARY_STYLE = preload("uid://fswaw5nxepqy")

const MAX_EQUIP_COUNT = 6

const UPGRADE_PROBABILITY_CONFIG = {
	"rare" : {"start_wave": 2, "base_multi": 0.06},
	"epic" : {"start_wave": 4, "base_multi": 0.02},
	"legendary" : {"start_wave": 7, "base_multi": 0.023},
}

const SHOP_PROBABILITY_CONFIG = {
	"rare" : {"start_wave": 2, "base_multi": 0.1},
	"epic" : {"start_wave": 4, "base_multi": 0.06},
	"legendary" : {"start_wave": 7, "base_multi": 0.01},
}

const TIER_COLOR: Dictionary[UpgradeTier, Color] = {
	UpgradeTier.RARE: Color(0.0, 0.557, 0.741),
	UpgradeTier.EPIC: Color(0.478, 0.251, 0.71),
	UpgradeTier.LEGENDARY: Color(0.906, 0.212, 0.212),
}

var player: Player
var game_paused := false
var coins: int = 1000
var equipped_weapons: Array[ItemWeapon] = []
var main_selected_player: UnitStats
var main_selected_weapon: ItemWeapon
var avaliable_players: Dictionary[String, PackedScene] = {
	"Brawler": preload("uid://desa3vwd4vj7w"),
	"Bunny": preload("uid://3aquq2ggi5qr"),
	"Crazy": preload("uid://bbqsvhuixjdpn"),
	"Knight": preload("uid://c8ivu38ascuhe"),
	"Well Rounded": preload("uid://beec7g4yfmy1e")
}

func get_selected_player() -> Player:
	var player_scene := avaliable_players[main_selected_player.name]
	player = player_scene.instantiate()
	return player

func get_harvesting_coins() -> void:
	if is_instance_valid(player):
		coins += player.stats.harvesting


func is_chance_success(chance: float) -> bool:
	var rate := randf_range(0, 1)
	return rate < chance

func get_tier_style(tier: UpgradeTier) -> StyleBoxFlat:
	match tier:
		UpgradeTier.RARE:
			return RARE_STYLE
		UpgradeTier.EPIC:
			return EPIC_STYLE
		UpgradeTier.LEGENDARY:
			return LEGENDARY_STYLE
		_:
			return COMMON_STYLE


func create_block_text(unit: Node2D) -> void:
	on_creat_block_text.emit(unit)
	
func create_damage_text(unit: Node2D, hitbox: HitboxComponent) -> void:
	on_create_damage_text.emit(unit, hitbox)

func upgrade_selected() -> void:
	on_upgrade_selected.emit()
	
func create_heal_text(unit: Node2D, heal: float) -> void:
	on_create_heal_text.emit(unit, heal)
	
func enemy_died(unit: Enemy) -> void:
	on_enemy_died.emit(unit)
	
func caculate_tier_probability(current_wave: int, config: Dictionary) -> Array[float]:
	var chances :Array[float] = [0.0,0.0,0.0,0.0]
	var configs := [null, config.rare, config.epic, config.legendary]
	var luck_factor := 1.0 + (Global.player.stats.luck / 100.0)
	for i in range(1, chances.size()):
		if current_wave >= configs[i].start_wave:
			chances[i] = min(1.0, (current_wave - configs[i].start_wave + 1) * configs[i].base_multi * luck_factor)
	var total_no_common_chance := chances.reduce(func(accum, number): return accum + number, 0) as float
	if total_no_common_chance > 1.0:
		var scale_down := 1.0 / total_no_common_chance
		for i in range(1, chances.size()):
			chances[i] *= scale_down
	chances[0] = max(0.0, 1.0 - total_no_common_chance)
	# Debug
	var debug_params := [current_wave, luck_factor]
	debug_params.append_array(chances)
	print_debug("Wave： %d, Luck： %.2f => Chances: C:%.2f, R:%.2f, E:%.2f, L:%.2f" % debug_params)
	
	return chances

func select_items_for_offer(item_pool: Array, current_wave: int, config: Dictionary) -> Array:
	var tier_chances := caculate_tier_probability(current_wave, config)
	var legendary_limit := tier_chances[3]
	var epic_limit := legendary_limit + tier_chances[2]
	var rare_limit := epic_limit + tier_chances[1]
	var offered_items:Array = []
	while offered_items.size() < tier_chances.size():
		var roll := randf()
		var chosen_tie_index := 0
		if roll < legendary_limit:
			chosen_tie_index = 3
		elif roll < epic_limit:
			chosen_tie_index = 2
		elif roll < rare_limit:
			chosen_tie_index = 1
		var potential_items :Array = []
		var current_search_tier_index := chosen_tie_index
		while potential_items.is_empty() and current_search_tier_index >= 0:
			potential_items = item_pool.filter(func(item: ItemBase):return item.item_tier == current_search_tier_index)
			if potential_items.is_empty():
				current_search_tier_index -= 1
			else:
				break
		if not potential_items.is_empty():
			var selected_item = potential_items.pick_random()
			if not offered_items.has(selected_item):
				offered_items.append(selected_item)
		else:
			break
	return offered_items
